package com.gitee.deament.server.core.cli.db.str;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.gitee.deament.server.config.SystemConfig;
import com.gitee.deament.server.core.annotation.CliHander;
import com.gitee.deament.server.core.cli.AbstractCli;
import com.gitee.deament.server.core.data.ConnectData;
import com.gitee.deament.server.core.data.DBData;
import com.gitee.deament.server.core.data.datatype.Value;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * 将字符串值 value 关联到 key 。
 * <p>
 * 如果 key 已经持有其他值， SET 就覆写旧值， 无视类型。
 * <p>
 * 当 SET 命令对一个带有生存时间（TTL）的键进行设置之后， 该键原有的 TTL 将被清除。
 *
 * @author yanyu
 * EX seconds ： 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。
 * <p>
 * PX milliseconds ： 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。
 * <p>
 * NX ： 只在键不存在时， 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。
 * <p>
 * XX ： 只在键已经存在时， 才对键进行设置操作。
 */
@CliHander(command = "SET")
public class SETcli extends AbstractCli {


    @Override
    public void executeCli(ChannelHandlerContext channelHandlerContext, String command) {
        DBData dbData = SystemConfig.dbData;
        List<String> values = getValues(command);
        if (values.size() < 3 || values.size() == 4 || values.size() > 5) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR wrong number of arguments for 'set' command"));
        }
        String key = values.get(1);
        String valuestr = values.get(2);
        int db = ConnectData.SELECT_DB_STORAGE.getUseDB(channelHandlerContext.channel().id().asLongText());
        Value<String> value = new Value<>();
        value.setValue(valuestr);
        if (values.size() == 5) {
            String secondCommand = values.get(4);
            if (NumberUtil.isInteger(values.get(5))) {
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("第五个参数不合法"));
            }
            Integer time = Integer.parseInt(values.get(5));
            LocalDateTime localDateTime = LocalDateTime.now();
            if (secondCommand.equalsIgnoreCase("EX")) {
             Date expirDate=   DateUtil.offset(new Date(), DateField.SECOND,time);
                value.setExpirDateTime(expirDate);
            } else if (secondCommand.equalsIgnoreCase("NX")) {
                String dbValue=   dbData.getStringData(db,key).getValue();
                if(dbValue==null){
                    dbData.setStringData(db, key, value);
                    channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("OK"));
                }
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("已存在该建"));
                return ;
            } else if (secondCommand.equalsIgnoreCase("PX")) {
                Date expirDate=   DateUtil.offset(new Date(), DateField.MILLISECOND,time);
                value.setExpirDateTime(expirDate);
            } else if (secondCommand.equalsIgnoreCase("XX")) {
                String dbValue=   dbData.getStringData(db,key).getValue();
                if(dbValue!=null){
                    dbData.setStringData(db, key, value);
                    channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("OK"));
                }
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("不已存在该建"));
                return ;
            } else {
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("第四个参数不合法"));
            }
        }

        dbData.setStringData(db, key, value);
        channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("OK"));

    }
}
